<template>
    <div class="white-box-form">
        <el-form
            ref="ruleRef"
            :model="state.ruleForm"
            :rules="state.rules"
            label-width="120px"
            class="mt-20"
        >
            <el-form-item label="角色名称" prop="roleName">
                <el-input
                    v-model.trim="state.ruleForm.roleName"
                    clearable
                    placeholder="请输入角色名称"
                    :disabled="state.disabledDeletable"
                />
            </el-form-item>
            <el-form-item label="角色权限key" prop="roleKey">
                <el-input
                    v-model.trim="state.ruleForm.roleKey"
                    clearable
                    placeholder="请输入角色权限key"
                    :disabled="state.disabledDeletable"
                />
            </el-form-item>
            <el-form-item label="菜单权限" prop="menuSids">
                <el-tree-select
                    v-model="state.ruleForm.menuSids"
                    :data="menuOptions"
                    node-key="sid"
                    filterable
                    multiple
                    check-strictly
                    collapse-tags
                    show-checkbox
                    :props="treeSelectProps"
                    placeholder="请选择菜单权限"
                    @check="onTreeCheckChange($event, 'menuSids')"
                >
                </el-tree-select>
            </el-form-item>
            <el-form-item label="小程序权限" prop="programsMenuSids">
                <el-tree-select
                    v-model="state.ruleForm.programsMenuSids"
                    :data="programsMenuOptions"
                    node-key="sid"
                    filterable
                    multiple
                    check-strictly
                    collapse-tags
                    show-checkbox
                    :props="treeSelectProps"
                    placeholder="请选择小程序权限"
                    @check="onTreeCheckChange($event, 'programsMenuSids')"
                >
                </el-tree-select>
            </el-form-item>
            <el-form-item label="角色等级" prop="level">
                <el-input-number
                    v-model="state.ruleForm.level"
                    :min="1"
                    :precision="0"
                    step-strictly
                    :disabled="state.disabledDeletable"
                />
            </el-form-item>

            <el-form-item label="数据范围" prop="dataScope">
                <el-select
                    v-model="state.ruleForm.dataScope"
                    placeholder="请选择数据范围"
                    clearable
                    :disabled="state.disabledDeletable"
                >
                    <el-option
                        v-for="item in state.scopeList"
                        :key="item.memberKey"
                        :label="item.memberName"
                        :value="item.memberKey"
                    />
                </el-select>
            </el-form-item>
            <el-form-item label="备注" prop="note">
                <el-input
                    v-model.trim="state.ruleForm.note"
                    type="textarea"
                    maxlength="100"
                    :autosize="{ minRows: 2 }"
                    clearable
                    show-word-limit
                    placeholder="请输入备注"
                />
            </el-form-item>
            <el-form-item label="状态" prop="status">
                <el-radio-group v-model="state.ruleForm.status">
                    <el-radio
                        v-for="item in state.statusList"
                        :key="item.memberKey"
                        :value="item.memberKey"
                        :disabled="state.disabledDeletable"
                        >{{ item.memberName }}</el-radio
                    >
                </el-radio-group>
            </el-form-item>
            <el-form-item label="是否可删除" prop="deletable">
                <el-radio-group v-model="state.ruleForm.deletable">
                    <el-radio
                        v-for="item in state.deletableList"
                        :key="item.memberKey"
                        :value="item.memberKey"
                        :disabled="state.disabledDeletable"
                        >{{ item.memberName }}</el-radio
                    >
                </el-radio-group>
            </el-form-item>
        </el-form>

        <div class="foot-btn">
            <el-button
                type="primary"
                :loading="state.form_loading"
                @click="submitForm(ruleRef)"
            >
                {{ isEdit ? "修改" : "添加" }}
            </el-button>
        </div>
        <go-back />
    </div>
</template>

<script setup>
import { inject, ref, onMounted, reactive, nextTick } from "vue";
import { useRouter, useRoute } from "vue-router";
import GoBack from "@components/GoBack.vue";
import { getRoleDetail, addRole, editRole } from "@/apis/system/role";
import { getRightMenusTree, getRightMiniMenusTree } from "@/apis/system/menu";
import { useDictStore } from "@stores/dict.js";

const dictStore = useDictStore();
dictStore.getDictMembers("data_status").then((res) => (state.statusList = res));
dictStore.getDictMembers("data_scope").then((res) => (state.scopeList = res));
dictStore
    .getDictMembers("deletable")
    .then((res) => (state.deletableList = res));

const $message = inject("$message");
const router = useRouter();
const route = useRoute();

const sid = route.query.sid;
const isEdit = ref(false);
const ruleRef = ref(null);
const state = reactive({
    statusList: [],
    scopeList: [],
    deletableList: [],
    pub_keys: "",
    roleOptions: [],
    ruleForm: {
        dataScope: null,
        deletable: 0,
        level: 1,
        menuSids: [],
        note: null,
        programsMenuSids: [],
        roleKey: null,
        roleName: null,
        status: 0,
    },
    rules: {
        roleKey: [
            { required: true, message: "请输入角色权限key", trigger: "blur" },
        ],
        roleName: [
            { required: true, message: "请输入角色名称", trigger: "blur" },
        ],
    },
    form_loading: false,
    disabledDeletable: false,
});

onMounted(async () => {
    await Promise.allSettled([getMenuOptions(), getProgramsMenuOptions()]);
    if (/Edit$/.test(route.name)) {
        isEdit.value = true;
        getDetail();
    }
});

const getDetail = async () => {
    const res = await getRoleDetail({ sid });
    if (res.data.code == 200) {
        state.ruleForm = res.data.data;
        state.disabledDeletable = state.ruleForm.deletable === 1;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const menuOptions = reactive([]);
const programsMenuOptions = reactive([]);
const treeSelectProps = {
    value: "sid",
    label: "menuName",
};
const getMenuOptions = async () => {
    const res = await getRightMenusTree();
    if (res.data.code == 200) {
        Object.assign(menuOptions, res.data.data);
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};
const getProgramsMenuOptions = async () => {
    const res = await getRightMiniMenusTree();
    if (res.data.code == 200) {
        Object.assign(programsMenuOptions, res.data.data);
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const onTreeCheckChange = (e, ruleFormKey) => {
    const isChecked = state.ruleForm[ruleFormKey].includes(e.sid);
    setCheckedChildren(e, isChecked, ruleFormKey);
};

// 递归选中/反选子节点
const setCheckedChildren = (e, isChecked, ruleFormKey) => {
    if (e.children) {
        e.children.forEach((item) => {
            const index = state.ruleForm[ruleFormKey].findIndex(
                (sid) => item.sid === sid
            );
            if (isChecked && index === -1) {
                state.ruleForm[ruleFormKey].push(item.sid);
            }
            if (!isChecked && index !== -1) {
                state.ruleForm[ruleFormKey].splice(index, 1);
            }
            setCheckedChildren(item, isChecked, ruleFormKey);
        });
    }
};

const submitForm = (formEl) => {
    if (!formEl) return;
    formEl.validate(async (valid, fields) => {
        if (valid) {
            state.form_loading = true;
            let res = null;
            if (isEdit.value) {
                // 修改
                res = await editRole(state.ruleForm);
            } else {
                // 新增
                res = await addRole(state.ruleForm);
            }
            state.form_loading = false;
            if (res.data.code == 200) {
                $message({
                    message: isEdit.value ? "修改成功" : "添加成功",
                    type: "success",
                });
                router.back();
            } else {
                $message({ message: res.data.msg, type: "error" });
            }
        }
    });
};
</script>

<style scoped lang="less"></style>
